package com.tzj.tg;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.Random;
import java.util.concurrent.CopyOnWriteArrayList;

import org.lwjgl.input.Keyboard;

import com.tzj.pic.Blast;
import com.tzj.pic.Bullet;
import com.tzj.pic.BulletComputer;
import com.tzj.pic.Grass;
import com.tzj.pic.Steel;
import com.tzj.pic.Tank;
import com.tzj.pic.TankComputer;
import com.tzj.pic.Wall;
import com.tzj.pic.Water;

import utils.Window;

/**
 * @author honeyrr
 *	窗口类
 */
public class GameWindow extends Window {

	private Tank tank;
	private CopyOnWriteArrayList<BasePicture> bpList = new CopyOnWriteArrayList<>();
	private ArrayList<TankComputer> tcList = new ArrayList<>(); 
	
	public GameWindow(String title, int width, int height, int fps) {
		super(title, width, height, fps);
	}

	/**
	 * 窗口创建时的回调
	 */
	@Override
	protected void onCreate() {
		tank = new Tank((Config.WIDTH - 64) / 2, Config.HEIGHT - 64);
		addPicture(tank);
		
		// 添加墙、铁、水、草
		for (int i = 0; i < 18; i++) {
			addPicture(new Wall(i * 64, 64 * 2));
		}
		for (int i = 1; i < 17; i++) {
			addPicture(new Water(i * 64, 64 * 3));
		}
		for (int i = 0; i < 18; i++) {
			if (i >= 7 && i <= 10) {
				continue;
			}
			addPicture(new Grass(i * 64, 64 * 5));
		}
		for (int i = 3; i < 15; i++) {
			addPicture(new Steel(i * 64, 64 * 7));
		}
		
		Config.play(Config.START);
		
		// 生成随机位置的5个电脑坦克
		for(int i = 0; i < 5; i++) {
			TankComputer tankComputer = new TankComputer((i * 3) * 64, new Random().nextInt(64));
			addPicture(tankComputer);
			tcList.add(tankComputer);
		}
	}

	/**
	 * 鼠标事件的监听
	 */
	@Override
	protected void onMouseEvent(int key, int x, int y) {

	}

	/**
	 * 键盘事件的监听
	 */
	@Override
	protected void onKeyEvent(int key) {
		switch (key) {
		case Keyboard.KEY_UP:
			tank.move(Dircetion.UP);
			break;
		case Keyboard.KEY_DOWN:
			tank.move(Dircetion.DOWN);
			break;
		case Keyboard.KEY_LEFT:
			tank.move(Dircetion.LEFT);
			break;
		case Keyboard.KEY_RIGHT:
			tank.move(Dircetion.RIGHT);
			break;
		case Keyboard.KEY_SPACE:
			// 当我方坦克血量不为0时，才能发射子弹
			if (!tank.isDestroyed()) {
				Bullet bullet = tank.shotBullet();
				if (bullet != null) {
					addPicture(bullet);
				}
			}
			break;

		default:
			break;
		}
	}

	/**
	 * 刷新方法每秒刷新Config.FPS次
	 */
	@Override
	protected void onDisplayUpdate() {
		// 游戏状态，是赢还是输
		gameState();
		
		// 用循环遍历将图形绘制出来
		for (BasePicture bp : bpList) {
			bp.draw();
			if (bp instanceof Destroyable) {
				if (((Destroyable) bp).isDestroyed()) {
					bpList.remove(bp);
					if (bp instanceof Blockable) {
						Config.play(Config.BLAST);
					}
					if (bp instanceof TankComputer) {
						tcList.remove((Destroyable)bp);
					}
				}
			}
		}
		
		// 坦克与墙铁水发生碰撞
		for (BasePicture bp1 : bpList) {
			for (BasePicture bp2 : bpList) {
				if(bp1 instanceof Moveable && bp2 instanceof Blockable && bp1 != bp2) {
					if (((Moveable)bp1).moveHit((Blockable)bp2)) {
						
						// 电脑坦克相互碰撞之后掉头
						if (bp1 instanceof TankComputer && bp2 instanceof TankComputer) {
							((TankComputer)bp1).setDircetion(reverDirection(((TankComputer)bp2).getDircetion()));
						}
						
						// 电脑坦克碰墙之后立马换方向
						if (bp1 instanceof TankComputer && (bp2 instanceof Steel || bp2 instanceof Wall || bp2 instanceof Water)) {
							getRandomDirection();
							((TankComputer)bp1).setDircetion(this.dircetion);
						}
						
						// 子弹打到敌方坦克，敌方坦克掉头跑
						if (bp1 instanceof Bullet && bp2 instanceof TankComputer) {
							((TankComputer)bp2).setDircetion(reverDirection(((Bullet)bp1).getDircetion()));
						}
						break;
					}
				}
			}
		}
		// 子弹与墙铁水发生碰撞
		for (BasePicture bp1 : bpList) {
			for (BasePicture bp2 : bpList) {
				if(bp1 instanceof Attackable && bp2 instanceof Hitable) {
					if (((Attackable)bp1).checkHit((Hitable)bp2)) {
						bpList.remove(bp1);
						Blast blast = ((Hitable)bp2).showBlast();
						bpList.add(blast);
						if (bp2 instanceof BulletComputer || bp2 instanceof Bullet) {
							bpList.remove(bp2);
						}
						break;// 当子弹打中两块砖之间是，只有拿到其中一块就跳出循环
					}
				}
			}
		}
		
		// 找到电脑坦克，让其自动游走并攻击
		for (BasePicture bp : bpList) {
			if (bp instanceof TankComputer) {
				((TankComputer) bp).move();
				BulletComputer bulletComputer = ((TankComputer) bp).shotBullet();
				if (bulletComputer != null) {
					addPicture(bulletComputer);
				}
			}
		}
		System.out.println(bpList.size());
	}

	/**
	 * 反方向
	 * @param dircetion
	 * @return
	 */
	private Dircetion reverDirection(Dircetion dircetion) {
		if (dircetion == Dircetion.UP) {
			return Dircetion.DOWN;
		} else if (dircetion == Dircetion.DOWN) {
			return Dircetion.UP;
		} else if (dircetion == Dircetion.LEFT) {
			return Dircetion.RIGHT;
		} else {
			return Dircetion.LEFT;
		}
		
	}

	
	private Random random = new Random();
	private Dircetion dircetion;
	
	/**
	 * 生成随机方向
	 */
	private void getRandomDirection() {
		int i = random.nextInt(4);
		if (i == 1) {
			this.dircetion = Dircetion.UP;
		} else if (i == 2) {
			this.dircetion = Dircetion.DOWN;
		} else if (i == 3) {
			this.dircetion = Dircetion.LEFT;
		} else {
			this.dircetion = Dircetion.RIGHT;
		}
	}
	/**
	 * 游戏状态
	 */
	private void gameState() {
		if (tank.isDestroyed() || (tank.isDestroyed() && tcList.size() == 0)) {
			bpList.clear();
			Config.draw(Config.OVER, 0, 0);
			Config.exitGame();
		}
		if (tcList.size() == 0) {
			bpList.clear();
			Config.draw(Config.WIN, 0, 0);
			Config.exitGame();
		}
//		boolean isHas = false;
//		for (BasePicture bp : bpList) {
//			if (bp instanceof TankComputer) {
//				isHas = true;
//			}
//		}
//		if (!isHas) {
//			bpList.clear();
//			Config.draw(Config.WIN, 0, 0);
//			Config.exitGame();
//		}
	}
	
	private void addPicture(BasePicture bp) {
		bpList.add(bp);
		// 按规则排序
		bpList.sort(new Comparator<BasePicture>() {

			@Override
			public int compare(BasePicture o1, BasePicture o2) {
				// TODO 自动生成的方法存根
				return o1.getOrder() - o2.getOrder();
			}
		});
	}

}
